#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0' || ch>'9') {
        if(ch=='-') f*=-1;
        ch=getchar();
    }
    while(ch<='9' && ch>='0') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int T,m,n;
ll pos[100005],a[100005],v[100005],d[100005],ans1,ans2,L,V,cnt=0,c[100005];
struct node {
    int l,r;
} G[100005];
inline int jd(int x) {
    //cout<<x<<endl;
    if(d[x]>pos[m]) return 0;
    if(a[x]==0) {
        return v[x]<=V?0:1;
    }
    else if(a[x]>0) {
        if((1ll*V*V)-(1ll*v[x]*v[x])>=1ll*2*a[x]*(pos[m]-d[x])) return 0;
        else return 1;
    }
    else {
        if(v[x]<=V) return 0;
        int pp=lower_bound(pos+1,pos+1+m,d[x])-pos;
        if((1ll*v[x]*v[x])-(1ll*V*V)<=1ll*(-2)*a[x]*(pos[pp]-d[x])) return 0;
        else return 1;
        //cout<<"! "<<x<<" "<<pp<<endl;
    }
}
inline bool check1(int x,int pp) {
    if(pos[pp]<d[x]) return 0;
    if((1ll*V*V)-(1ll*v[x]*v[x])>=1ll*2*a[x]*(pos[pp]-d[x])) return 0;
    return 1;
}
inline void solve(int x,int id) {
    int res=0;
    if(a[x]==0) {
        G[id].l=lower_bound(pos+1,pos+1+m,d[x])-pos,G[id].r=m;
    }
    else if(a[x]>0) {
        G[id].r=m;
        int lx=1,ly=m;
        while(lx<=ly) {
            int mid=(lx+ly)>>1;
            //cout<<mid<<endl;
            if(pos[mid]>=d[x] && (1ll*V*V)-(1ll*v[x]*v[x])<1ll*2*a[x]*(pos[mid]-d[x])) {
                res=mid;
                ly=mid-1;
            }
            else lx=mid+1;
        }
        G[id].l=res;
    }
    else {
        G[id].l=lower_bound(pos+1,pos+1+m,d[x])-pos;
        int lx=G[id].l,ly=m;
        while(lx<=ly) {
            int mid=(lx+ly)>>1;
            //cout<<mid<<endl;
            if((1ll*v[x]*v[x])-(1ll*V*V)>1ll*(-2)*a[x]*(pos[mid]-d[x])) {
                //cout<<"!"<<endl;
                res=mid;
                lx=mid+1;
            }
            else ly=mid-1;
        }
        G[id].r=res;
    }
}  
inline bool cmp(node n1,node n2) {
    if(n1.l!=n2.l) return n1.l<n2.l;
    else return n1.r<n2.r;
}
int main() {
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--) {
        n=read(),m=read(),L=read(),V=read();
        cnt=ans2=ans1=0;
        for(int i=1;i<=n;++i) {
            d[i]=read(),v[i]=read(),a[i]=read();
        }
        for(int i=1;i<=m;++i) pos[i]=read();
        for(int i=1;i<=n;++i) {
            if(jd(i)) {
                //cout<<i<<endl;
                ans1++;
                c[++cnt]=i;
            }
        }
        for(int i=1;i<=cnt;++i) {
            solve(c[i],i);
            //cout<<c[i]<<" "<<G[i].l<<" "<<G[i].r<<endl;
        }
        sort(G+1,G+1+cnt,cmp);
        //for(int i=1;i<=cnt;++i) cout<<i<<" "<<G[i].l<<" "<<G[i].r<<endl;
        for(int i=1,j;i<=cnt;) {
            int tmp=G[i].r;
            for(j=i+1;j<=cnt;++j) {
                if(tmp<G[j].l) break;
                tmp=min(tmp,G[j].r);
            }
            ans2++;
            i=j;
        }
        ans2=m-ans2;
        printf("%lld %lld\n",ans1,ans2);
    }
    return 0;
}